<?php

namespace Modules\Common\General\Security\Api;
use Closure;
use Exception;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Firebase\JWT\JWT;
use Illuminate\Support\Facades\Auth;
use Modules\Common\Models\Users;
use Modules\Common\Models\Members;
use Modules\Common\Models\ActivationCodes;
use Modules\Common\Models\SubscriptionRecords;
use Modules\Common\Util\Api;
use Carbon\Carbon;

class GatewayMiddleware extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //植入一个定时更新会员是否过期和阅读卡是否过期的处理任务
        // 获取当前时间
        $now = Carbon::now();
        
        // 更新已过期的会员状态
        Members::where('status', 1)  // 假设1表示激活状态
            ->where('end_date', '<', $now)  // 过期时间小于当前时间
            ->update(['status' => 2]);  // 假设2表示过期状态
        
        // 更新已过期的激活码状态
        ActivationCodes::where('status', 1)
            ->where('expire_time', '<', $now)
            ->update(['status' => 3]);
            
        SubscriptionRecords::where('status', 1)  // 假设1表示激活状态
            ->where('end_date', '<', $now)  // 过期时间小于当前时间
            ->update(['status' => 3]);
            
         // 检查是否是后台管理路由
        if ($request->is('api/admin/*') || $request->is('api/upload/*')) {
            $this->handleAdminRequest($request);
        } elseif($request->is('api/h5/*')) {
            // 处理其他请求，例如 H5 登录
            $this->handleOtherRequest($request);
        }
    
        return $next($request);
    }
    
    protected function handleAdminRequest($request)
    {
        $token = $this->getTokenFromAuthorizationHeader($request);
        if (!$token) {
            throw new Exception('token不存在', '402');
        }
    
        $request->headers->set("Authorization", "Bearer " . $token);
        try {
            if (! $this->auth->parser()->setRequest($request)->hasToken()) {
                throw new Exception('token不存在', '402');
            }
            if (! $this->auth->parseToken()->authenticate()) {
                throw new Exception('用户不存在', '401');
            }
            $token_jwt = JWT::decode($token, config('jwt.secret'), ['HS256']);
            $token_jwt = (array) $token_jwt; // 转换为数组，以便合并
            // 获取用户信息
            $decoded = Auth::user();
            // 将 JWT 信息嵌入到用户对象中
            $decoded->token_info = $token_jwt;
            // 将嵌入了 JWT 信息的用户对象存储到 API 认证守卫中
            Auth::guard('api')->setUser($decoded);
        } catch (TokenExpiredException $e) {
            throw new Exception('token过期，请重新登录', '403');
        } catch (JWTException $e) {
            throw new Exception($e->getMessage(), $e->getCode());
        }
    }
    
    protected function handleOtherRequest($request)
    {
        // 处理 H5 登录请求
        $token =$request->headers->get('Authorization'); // 从请求头中获取 Token
        
        if (!$token) {
            // 如果没有 Token，返回错误响应
            throw new Exception('token不存在', '402');
        }
        try {
            // 尝试解码 Token
            $decoded = JWT::decode($token, "JWT-ARY-STARK", ['HS256']);
            $userId = $decoded->customer->id;
            if (isset($userId)) {
                $user = Users::where('id', $userId)->first();
                if (!$user) {
                    throw new Exception('用户不存在', '401');
                }
                Auth::guard('web')->setUser($user);
            } else {
                throw new Exception('token异常', '404');
            }
        } catch (TokenExpiredException $e) {

            // 如果 Token 过期，返回过期错误
            throw new Exception('token过期，请重新登录', '403');
        } catch (JWTException $e) {
            // 如果发生其他 JWT 错误，返回通用错误
            throw new Exception($e->getMessage(), $e->getCode());
        }
    }

    
    protected function getTokenFromAuthorizationHeader($request)
    {
        $authorizationHeader = $request->headers->get('Authorization');
        if ($authorizationHeader) {
            $parts = explode(' ', $authorizationHeader);
            if (count($parts) === 2 && $parts[0] === 'Bearer') {
                return $parts[1];
            }
        }
        return null;
    }
}
